import dayjs from 'dayjs'
import type { IndexObj } from '@/types/commom'
import settingsStore from '@/stores/modules/settings'

// 去除前后空格
export const noSideSpace = (value: string) =>
  !value.startsWith(' ') && !value.endsWith(' ')

// 只允许输入数字
export const onlyAllowNumber = (value: string) => !value || /^\d+$/.test(value)

// 将数字没三个逗号一隔开
export function addCommas(str: string) {
  return str.replace(/\d(?=(\d{3})+$)/g, '$&,')
}

// 防抖函数
export function debounce(func: Function, delay: number) {
  let timer: ReturnType<typeof setTimeout> | null
  return function (this: any, ...args: any[]) {
    clearTimeout(timer!)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}

// 防抖函数
export function throllte(func: Function, delay: number) {
  let timer: ReturnType<typeof setTimeout> | null
  return function (this: any, ...args: any[]) {
    if (timer) {
      return
    }
    timer = setTimeout(() => {
      func.apply(this, args)
      clearTimeout(timer!)
      timer = null
    }, delay)
  }
}

// 字节转换为其他单位
export function convertFromBytes(bytes: string) {
  const units: IndexObj<bigint> = {
    B: 1n,
    KB: 1024n,
    MB: 1024n ** 2n,
    GB: 1024n ** 3n,
    TB: 1024n ** 4n
  }

  let unit = 'B'
  let value = BigInt(bytes)

  for (const key of Object.keys(units).reverse()) {
    if (value >= units[key]) {
      unit = key
      value = value / units[key]
      break
    }
  }

  // const formattedValue = parseFloat(value.toString()).toFixed(2)
  // return `${formattedValue}${unit}`

  return `${value.toString()}${unit}`
}

// GB、KB、MB等转换为字节
export function convertToBytes(size: string) {
  const regex = /^(\d+)([A-Za-z]+)$/ // 正则表达式匹配数字和单位
  const units: IndexObj<bigint> = {
    B: 1n,
    KB: 1024n,
    MB: 1024n ** 2n,
    GB: 1024n ** 3n,
    TB: 1024n ** 4n
  }

  const matches = size.match(regex)
  if (!matches) {
    throw new Error('Invalid size')
  }

  const value = BigInt(matches[1])
  const unit = matches[2].toUpperCase()

  if (!units[unit]) {
    throw new Error('Invalid unit')
  }

  return value * units[unit] + ''
}

// 根据字节数，和传入的单位，返回转换为的数值
export function convertBytes(bytes: string, unit: string) {
  const units: IndexObj<bigint> = {
    B: 0n,
    KB: 1n,
    MB: 2n,
    GB: 3n,
    TB: 4n,
    PB: 5n
  }

  const base = 1024n
  const exponent = units[unit.toUpperCase()]

  if (exponent === undefined) {
    throw new Error('Invalid unit')
  }

  const convertedSize = BigInt(bytes) / base ** exponent
  return convertedSize + ''
}

// 获取到数字部分
export function extractNumbers(str: string) {
  const regex = /\d+/g
  const matches = str.match(regex)
  return matches ? matches.join('') : ''
}

// 格式化时间
export const formatTime = (str: string, format = 'YYYY-MM-DD HH:mm:ss') => {
  format = settingsStore().dateFormat
  return dayjs(str).format(format)
}

// 根据类型获取今天，近7天，近30天的startTime和endTime
export const getStartAndEndTime = (type: number) => {
  // 获取今天的日期
  // 获取当前日期
  const today = dayjs()

  let startTime = null
  const endTime = today.endOf('day')
  if (type === 0) {
    startTime = today.startOf('day')
  } else if (type === 1) {
    // 计算开始时间：今天的日期减去6天
    startTime = today.subtract(6, 'day').startOf('day')
  } else if (type === 2) {
    startTime = today.subtract(29, 'day').startOf('day')
  }

  return {
    startTime,
    endTime
  }
}

// 数组拍平，根据children
export function flattenArrayByChildren(
  arr: any[],
  childName = 'children'
): any[] {
  const flatArray: any[] = []

  function flatten(node: any) {
    flatArray.push({ ...node })

    if (node[childName]) {
      node[childName].forEach((child: any) => {
        flatten(child)
      })
    }
  }

  arr.forEach((node) => {
    flatten(node)
  })

  return flatArray
}

// 数组树形化
export const arrayToTree = (
  items: any[],
  pName: any = 'pid',
  parentId: any = null
) => {
  const result: any[] = []

  items.forEach((item) => {
    if (item[pName] === parentId) {
      const children = arrayToTree(items, pName, item.id)
      if (children.length) {
        item.children = children
      }
      result.push(item)
    }
  })

  return result
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 判断两个数组是否相等
 * @param {*} array1
 * @param {*} array2
 */
export const arraysIsEqual = (array1: any[], array2: any[]) => {
  if (array1.length !== array2.length) {
    return false
  }
  for (let i = 0; i < array1.length; i++) {
    if (array1[i] !== array2[i]) {
      return false
    }
  }
  return true
}

/**
 * 根据当前data数据的名称，获取下一个不重名文件的名称
 * @param data 原有数据数组
 * @param filename 需要不重名的名称
 * @param getMax 是否获取下一个num
 * @returns
 */
export const formatFilenameByInc = (
  data: any[],
  filename: string,
  getMax = false
) => {
  const lastIndex = filename.lastIndexOf('.')
  let first = filename
  let suffix = ''
  if (lastIndex !== -1) {
    first = filename.substring(0, lastIndex)
    suffix = filename.substring(lastIndex)
  }

  let names: any = data
    .filter((item) => {
      return item.filename.startsWith(first)
    })
    .map((item) => {
      return {
        filename: item.filename
      }
    })

  const reg = new RegExp(`^${first}([(](\\d+)[)])?${suffix}$`)
  names = names
    .filter((item: any) => {
      // 这个names 即为xxx,应该满足一下正则/^first.*suffix$/
      if (reg.test(item.filename)) {
        item.filename.replace(reg, (p: any, p1: any, p2: any) => {
          // 如果p2为undeined，说明为xxx.png
          if (!p2) {
            item.filename = 0
          } else {
            item.filename = Number(p2)
          }
        })
        return true
      }
      return false
    })
    .map((item: any) => item.filename)

  let max = 0
  // 如果names数组为0，说明没人满足正则，也就是不重复
  if (names.length) {
    max = Math.max.apply(null, names) + 1
  }
  if (getMax) {
    return max
  }
  if (max === 0) {
    return `${first}${suffix}`
  } else {
    return `${first}(${max})${suffix}`
  }
}

/**
 * 解析出token的载荷信息
 */
export const parseToken = (token: string) => {
  // 将 token 按照 . 分割成三部分，并取第二部分（即 payload 部分）
  const base64Url = token.split('.')[1]

  // 使用 atob() 解码 base64 编码的 payload
  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
  const payload = decodeURIComponent(
    atob(base64)
      .split('')
      .map(function (c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
      })
      .join('')
  )

  // 解析 JSON 格式的 payload
  return JSON.parse(payload)
}

export const uniqueArrayByKey = (array: any[], key: string) => {
  return array.filter((item, index, self) =>
    index === self.findIndex((t) => t[key] === item[key])
  );
}
